package pikes.ecma;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class FunctionCall extends PrintableExpression implements ICallExpression {

	private IMemberExpression memberExpression = null;

	private List<IAssignmentExpression> arguments = new LinkedList<IAssignmentExpression>();

	public FunctionCall(final CharSequence identifier) {
		this(new Identifier(identifier));
	}

	public FunctionCall(CharSequence identifier, CharSequence firstArgument) {
		this(new Identifier(identifier), new Identifier(firstArgument));
	}

	public FunctionCall(IMemberExpression memberExpression) {
		this.memberExpression = memberExpression;
	}

	public FunctionCall(CharSequence identifier, IAssignmentExpression firstArgument) {
		this(new Identifier(identifier), firstArgument);
	}

	public FunctionCall(IMemberExpression memberExpression, CharSequence firstArgument) {
		this(memberExpression, new Identifier(firstArgument));
	}

	public FunctionCall(IMemberExpression memberExpression, IAssignmentExpression firstArgument) {
		this.memberExpression = memberExpression;
		addArgument(firstArgument);
	}

	public void visit(SyntaxTreeVisitor syntaxTreeVisitor) throws EcmaSyntaxVisitingException {
		memberExpression.visit(syntaxTreeVisitor);
		syntaxTreeVisitor.beforeParameterList();
		Iterator<IAssignmentExpression> iArguments = arguments.iterator();
		while (iArguments.hasNext()) {
			iArguments.next().visit(syntaxTreeVisitor);
			if (iArguments.hasNext()) {
				syntaxTreeVisitor.comma();
			}
		}
		syntaxTreeVisitor.afterParameterList();
	}

	public void addArgument(IAssignmentExpression argument) {
		arguments.add(argument);
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof FunctionCall)) {
			return false;
		}

		FunctionCall thatFunctionCall = (FunctionCall) obj;

		if (!(memberExpression.equals(thatFunctionCall.memberExpression))) {
			return false;
		}

		if (!(arguments.equals(thatFunctionCall.arguments))) {
			return false;
		}

		return true;
	}

	@Override
	public int hashCode() {

		int hash = 0;

		hash = hash + memberExpression.hashCode();

		for (IAssignmentExpression expression : arguments) {
			hash = hash + expression.hashCode();
		}
		return hash;
	}

}
